package com.vvlive.caibao.smartcity.callback;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

import com.vvlive.caibao.smartcity.base.CalendarViews;
import com.vvlive.caibao.smartcity.base.GetDeptInfo;
import com.vvlive.caibao.smartcity.base.MeetingsListInterface;
import com.vvlive.caibao.smartcity.bean.Dept;
import com.vvlive.caibao.smartcity.bean.MeetingByMonth;
import com.vvlive.caibao.smartcity.bean.MeetingRoom;
import com.vvlive.caibao.smartcity.bean.NewMeetingInfo;
import com.vvlive.caibao.smartcity.bean.WeekCell;
import com.vvlive.caibao.smartcity.bean.WeekCellUI;
import com.vvlive.caibao.smartcity.bean.WeekRow;
import com.vvlive.caibao.smartcity.fragment.PagerAllMeetingsFragment;
import com.vvlive.caibao.smartcity.ui.OrderOneMeetingActivity;
import com.vvlive.caibao.smartcity.utils.MeetingsController;
import com.vvlive.caibao.smartcity.view.CellEventCard;
import com.vvlive.caibao.smartcity.view.WeekView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by zhj on 2015/11/12.
 */
public class WeekCallBack implements MeetingsListInterface.OnMeetingsPreparedListener,
                                             GetDeptInfo.OnLoadFinishListener, WeekView.OnCellClickListener,
                                             MeetingsListInterface.OnMeetingsRefreshListener {

    private List<MeetingRoom> currentRooms;
    private List<MeetingByMonth> meetingByMonths;

    private Map<Dept, List<MeetingRoom>> mDeptInfo = new HashMap<>();
    private Map<MeetingRoom, List<MeetingByMonth>> mRoomInfo = new HashMap<>();
    private CalendarViews.OnRefreshListener mRefresh;

    /**
     * 所有的机构
     */
    private List<Dept> depts = new ArrayList<>();
    /**
     * 所有的会议室，不分机构
     */
    private List<MeetingRoom> mMeetingRooms = new ArrayList<>();

    private Context context;
    private Calendar calendar;
    private WeekView weekView;
    private GetDeptInfo getDeptInfo;

    public WeekCallBack(Context context, Calendar calendar,
                        WeekView weekView, GetDeptInfo getDeptInfo) {
        this.context = context;
        this.calendar = calendar;
        this.weekView = weekView;
        this.getDeptInfo = getDeptInfo;
    }

    @Override
    public void onGetMeetings(List<MeetingByMonth> meetingBeans) {
        meetingByMonths = meetingBeans;
        getDeptInfo.load(this);
        if(mRefresh != null){
            mRefresh.onFinish(CalendarViews.REFRESH_SUCCESS);
        }
    }

    @Override
    public void onLoadError(int errCode, String str) {
        if(mRefresh != null){
            mRefresh.onFinish(CalendarViews.REFRESH_FAILURE);
        }
    }

    @Override
    public void onLoadFinish(List<Dept> depts, List<MeetingRoom> rooms) {
        this.depts = depts;
        this.mMeetingRooms = rooms;
        // 把会议室按照部门分类
        for (Dept dept : depts) {
            List<MeetingRoom> meetingRooms = new ArrayList<>();
            for (MeetingRoom room : rooms) {
                String currentRoomId = room.getRoomid();
                if (dept.getDeptid().equals(room.getDeptid())) {
                    // 把会议按照会议室分类
                    List<MeetingByMonth> meetings = new ArrayList<>();
                    for (MeetingByMonth mbm : meetingByMonths) {
                        if (currentRoomId.equals(mbm.getRoomid())) {
                            meetings.add(mbm);
                        }
                    }
                    meetingRooms.add(room);
                    mRoomInfo.put(room, meetings);
                }

            }
            mDeptInfo.put(dept, meetingRooms);
        }

        weekView.addHeader(new String[]{"", "一", "二", "三", "四", "五", "六", "日"});
        Dept key = (Dept) mDeptInfo.keySet().toArray()[0];
        weekView.addRows(getWeekRows(key));
        addWeekCellUIs(getWeekCellUIListByDept(key));

    }

    /**
     * 根据机构获取每一天的会议显示UI
     *
     * @param dept
     * @return
     */
    public List<WeekCellUI> getWeekCellUIListByDept(Dept dept) {
        List<MeetingRoom> roomsOfDept = null;
        for (Dept d : depts) {
            if (d.getDeptid().equals(dept.getDeptid())) {
                roomsOfDept = mDeptInfo.get(d);
            }
        }

        return getWeekCellUIListByMeetingRooms(roomsOfDept.toArray(new MeetingRoom[roomsOfDept.size()]));
    }

    /**
     * 根据会议室会获取每一天的会议显示UI
     *
     * @param meetingRooms
     * @return
     */
    public List<WeekCellUI> getWeekCellUIListByMeetingRooms(MeetingRoom[] meetingRooms) {
        List<MeetingRoom> rooms = Arrays.asList(meetingRooms);
        currentRooms = rooms;
        List<WeekCellUI> uis = new ArrayList<>();
        int[] dates = getDatesOfCurrentWeek();
        for (int i = 0, roomSize = rooms.size(); i < roomSize; i++) {  // row

            List<MeetingByMonth> meetingsOfRoom = null;
            MeetingRoom room = rooms.get(i);
            for (MeetingRoom m : mMeetingRooms) {
                if (m.getRoomid().equals(room.getRoomid())) {
                    meetingsOfRoom = mRoomInfo.get(m);
                    break;
                }
            }

            if (meetingsOfRoom == null || meetingsOfRoom.isEmpty()) continue;

            for (int j = 0, len = dates.length; j < len; j++) {  // col
                int day = dates[j];
                List<String> titles = new ArrayList<>();
                for (int k = 0, meetingSize = meetingsOfRoom.size(); k < meetingSize; k++) {

                    MeetingByMonth byMonth = meetingsOfRoom.get(k);
                    Date date = new Date(MeetingsController.getStartDateTimeInMillis(byMonth.getTime()));
                    boolean isTheSameDay = (day == date.getDate() &&
                                                    calendar.get(Calendar.MONTH) == date.getMonth());

                    if (isTheSameDay) {
                        titles.add(byMonth.getTopic() + " " + byMonth.getTime().split(" ")[1].split("-")[0]);
                    }

                }

                if (!titles.isEmpty()) {
                    WeekCellUI ui = new WeekCellUI();
                    ui.titles = titles;
                    ui.row = i;
                    ui.col = j;
                    uis.add(ui);
                }
            }
        }
        return uis;
    }

    /**
     * @param dept
     * @return
     */
    public List<WeekRow> getWeekRows(Object dept) {
        List<MeetingRoom> rooms = mDeptInfo.get(dept);
        return getWeekRowsByRooms(rooms.toArray(new MeetingRoom[rooms.size()]));
    }

    public List<WeekRow> getWeekRowsByRooms(MeetingRoom[] rooms) {
        List<WeekRow> weekRows = new ArrayList<>();
        List<MeetingRoom> roomsList = Arrays.asList(rooms);
        int cols = roomsList.size();
        for (int i = 0; i < cols; i++) {

            WeekRow weekRow = new WeekRow();
            weekRow.setIsChecked(false);
            List<WeekCell> weekCells = new ArrayList<>();
            for (int j = 0; j < 8; j++) {
                WeekCell weekCell = new WeekCell();
                weekCell.setIsChecked(false);
                if (j == 0) {
                    weekCell.setText(roomsList.get(i).getRoom());
                } else {
                    weekCell.setText("");
                }
                weekCells.add(weekCell);
            }
            weekRow.setWeekCells(weekCells);
            weekRows.add(weekRow);
        }

        return weekRows;
    }

    /**
     * @return
     */
    public List<MeetingByMonth> getMeetings() {
        return meetingByMonths;
    }

    public List<Dept> getDepts() {
        return depts;
    }

    public List<MeetingRoom> getMeetingRooms() {
        return mMeetingRooms;
    }

    @Override
    public void onCellClick(View view, WeekCell cell) {
        NewMeetingInfo info = new NewMeetingInfo();
        MeetingRoom room = currentRooms.get(cell.getRow());
        Dept dept = findDeptByRoom(room);
        info.setRoom(new String[]{room.getRoomid(), room.getRoom()});
        info.setDept(new String[]{dept.getDeptid(), dept.getDeptname()});
        long startMillis = System.currentTimeMillis();
        long endMillis = getEndTimeMillis(startMillis);
        info.setStartTime(startMillis);
        info.setEndTime(endMillis);
        Intent intent = new Intent(context, OrderOneMeetingActivity.class);
        Bundle bundle = new Bundle();
        bundle.putSerializable(PagerAllMeetingsFragment.NEW_MEETING_INFO_KEY, info);
        intent.putExtras(bundle);
        ((Activity) context).startActivityForResult(intent, 0);
    }

    private long getEndTimeMillis(long startMillis) {
        return startMillis + 1000 * 60 * 30;
    }

    /**
     * @param dept
     * @return
     */
    private List<MeetingRoom> findRoomsByDept(Dept dept) {
        List<MeetingRoom> rooms = new ArrayList<>();
        for (MeetingRoom room : mMeetingRooms) {
            if (dept.getDeptid().equals(room.getDeptid())) {
                rooms.add(room);
            }
        }
        return rooms;
    }

    public List<MeetingByMonth> findMeetingsByRooms(MeetingRoom[] rooms) {
        List<MeetingByMonth> meetings = new ArrayList<>();
        for (MeetingByMonth meeting : meetingByMonths) {
            for (MeetingRoom room : rooms) {
                if (room.getRoomid().equals(meeting.getRoomid())) {
                    meetings.add(meeting);
                    break;
                }
            }
        }
        return meetings;
    }

    /**
     * @param room
     * @return
     */
    private Dept findDeptByRoom(MeetingRoom room) {
        for (Dept dept : depts) {
            if (dept.getDeptid().equals(room.getDeptid())) {
                return dept;
            }
        }
        return new Dept();
    }

    public void addWeekCellUIs(List<WeekCellUI> weekCellUIs) {
        for (WeekCellUI ui : weekCellUIs) {
            List<String> titles = ui.titles;
            CellEventCard card = new CellEventCard(context);
            for (String title : titles) {
                card.addItem(title);
            }
            weekView.replaceCell(card, ui.row, ui.col);
        }
    }

    /**
     * Get days of current week
     *
     * @return
     */
    public int[] getDatesOfCurrentWeek() {
        int[] dates = new int[7];
        calendar.setTimeInMillis(calendar.getTimeInMillis());
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (dayOfWeek == 0) {
            dayOfWeek = 7;
        }
        calendar.add(Calendar.DATE, -dayOfWeek + 1);
        dates[0] = calendar.get(Calendar.DAY_OF_MONTH);
        for (int i = 1; i < 7; i++) {
            dates[i] = dates[i - 1] + 1;
        }
        return dates;
    }

    public void setCalendar(Calendar calendar) {
        this.calendar = calendar;
    }

    @Override
    public void onFailure(int code, String msg) {

    }

    public void setOnRefreshListener(CalendarViews.OnRefreshListener onRefreshListener){
        mRefresh = onRefreshListener;
    }
}
